<?php


/** ensure this file is being included by a parent file */
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

/**
 * @package	
 */
class HelpDeskFile extends HelpDeskObject {

	/**
	 * constructor (registers additional tasks to methods)
	 * @return void
	 */
	function __construct() {
		
	}

	/**
	 * Returns 
	 * @param object
	 * @param object Valid JUser Object
	 * @param object Valid TableFile Object
	 * @param mixed 
	 * @return array
	 */
	function doUpload ( $ticket, $user, $file, $fieldname='userfile' ) {
		global $database, $mainframe;
		$config = &HelpDeskConfig::getInstance();
		$date = $mainframe->now;

		$success = false;
		
		// invalid entries
		if ( !$this->handleUpload( 'userfile' ) ) {
        	return $success;
		}	
				
		// invalid ticket
		if ( !$ticket->id ) {
        	$this->setError( HelpDeskText::_( 'Invalid Ticket' ) );
        	return $success;
		}

		// ticket not assoc with user
		if ( !$canView = &HelpDeskHelperHelpDesk::canViewTicket( $ticket->id, $user->id ) ) {
        	$this->setError( HelpDeskText::_( 'Invalid Ticket' ) );
        	return $success;
		}		

		// if config says to use blob, create blob
		$storeasblob = $config->get( 'files_storagemethod', '1' );
		if ($storeasblob == '2') {
			$this->fileToBlob();			
		} else {
			// otherwise, store as file
			$this->fileisblob = 0;
			$this->setDirectory();
		}
		
		// create random physical name
		$physicalname = $this->createPhysicalName();
								
		// store the file
		$file->physicalname		= $physicalname;
		$file->ticketid			= $ticket->id;
		$file->userid			= $user->id;
		$file->datetime			= $date;
		$file->filename			= $this->proper_name;
		$file->fileextension	= $this->extension;
		$file->filesize			= $this->size;
		$file->fileisblob		= $this->fileisblob;
		if ( $file->store() ) {
			$success = true;
		}
			
		if ($file->fileisblob == '1') {
			$query = " INSERT INTO #__helpdesk_fileblobs " 
					. " SET `fileid` = '".$file->id."', "
					. " `fileblob` = '".$this->fileasblob."' "
			;
			$database->setQuery( $query );
			$database->query();
		} else {
			// move the file to the appropriate dir
			$dest = $this->_directory.DS.$file->physicalname;
			@rename($this->file_path, $dest);			
		}
		return $success;
	}
	
	/**
	 * Returns a list of types
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function setDirectory() {
		$success = false;

		// checks to confirm existence of directory
		// then confirms directory is writeable		
		$dir = $this->getDirectory();
		if (!$exists = file_exists( $dir ) ) {
			$create = mkdir( $dir );
		} else {
			if (!is_writable($dir)) {
				$change = @chmod( $dir, octdec('0755') );
			}
		}

		// then confirms existence of htaccess file
		$htaccess = $dir.DS.'.htaccess';
		if (!$fileexists = file_exists( $htaccess ) ) {

			$destination = $htaccess;
			$text = "deny from all";
			
			if ($f = @fopen($destination,'wb')) {
				fwrite ( $f, $text );
				fclose($f);
			}

		}
				
		$success = true;
		return $success;
	}

	/**
	 * Returns a list of types
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function getDirectory () {

		if (!isset($this->_directory)) {
			// checks config for upload store directory?
			$this->_directory = JPATH_SITE.DS.'images'.DS.'attachmentshelpdesk';
		}
				
		return $this->_directory;
	}

	/**
	 * Returns a list of types
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function getTempDirectory () 
	{
		global $mosConfig_absolute_path;
		if (!isset($this->_temppath)) {
			// checks config for upload temp directory?
			// $this->_temppath = $mosConfig_absolute_path.DS.'images'.DS.'tmp';
            // Try to use system's temporary directory
            // as random name shouldn't exist
            $temp_file = tempnam( md5(uniqid(rand(), TRUE)), '' );
            if ( $temp_file ) {
                $temp_dir = realpath( dirname($temp_file) );
                unlink( $temp_file );
                $this->_temppath = $temp_dir;
            } else {
                $this->_temppath = $mosConfig_absolute_path.DS.'images'.DS.'tmp';
            }			
		}

		if (!$exists = file_exists( $this->_temppath ) ) {
			$create = mkdir( $this->_temppath );
		} else {
			if (!is_writable( $this->_temppath )) {
				$change = @chmod( $this->_temppath, octdec('0755') );
			}
		}		
				
		return $this->_temppath;
	}
			
	/**
	 * Returns 
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return object
	 */
	function handleUpload ($fieldname='userfile') {
		$success = false;
		$config = &HelpDeskConfig::getInstance();
		
		// Check if file uploads are enabled
		if (!(bool)ini_get('file_uploads')) {
			$this->setError( HelpDeskText::_( 'Uploads Disabled' ) );
			return $success;
		}
	
		// Check that the zlib is available
		if(!extension_loaded('zlib')) {
			$this->setError( HelpDeskText::_( 'ZLib Unavailable' ) );
			return $success;
		}

		// check that upload exists
		$userfile = mosGetParam( $_FILES, $fieldname, '', '' );
		if (!$userfile) {
			$this->setError( HelpDeskText::_( 'No File' ) );
			return $success;
		}
		
		$this->proper_name = basename($userfile['name']);
		
		if ($userfile['size'] == 0) {
			$this->setError( HelpDeskText::_( 'Invalid File' ) );
			return $success;
		}
		
		$this->size = $userfile['size']/1024;		
		// check size of upload against max set in config
		if($this->size > $config->get( 'files_maxsize', '3000' ) ) {
			$this->setError( HelpDeskText::_( 'Invalid File Size' ) );
			return $success;
	    }
	    $this->size = number_format( $this->size, 2 ).' Kb';
		
		if (!is_uploaded_file($userfile['tmp_name'])) {
			$this->setError( HelpDeskText::_( 'Invalid File' ) );
			return $success;
	    } else {
	    	$this->file_path = $userfile['tmp_name'];
		}
		
		$this->getExtension();
		$this->uploaded = true;
		$success = true;
		
		return $success;
	}

	/**
	 * Returns a list of types
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function getExtension () {
		if (!isset($this->extension)) {
			$namebits = explode('.', $this->proper_name);
			$this->extension = $namebits[count($namebits)-1];
		}
				
		return $this->extension;
	}

	/**
	 * Returns a unique physical name
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function createPhysicalName() {
		global $mosConfig_secret;
		$dir = $this->getDirectory();
		$extension = $this->getExtension();
		$name = md5( $mosConfig_secret .  time()  );
		$physicalname = $name.".".$extension;
		
		while ($fileexists = file_exists( $dir.DS.$physicalname ) ) {
			$name = md5( $mosConfig_secret .  time()  );
			$physicalname = $name.".".$extension;
		}
				
		return $physicalname;
	}	
	
	/**
	 * Returns 
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function fileToText () {
		global $database;
		$source = $this->file_path;
		$success = false;
		
		if ($f = @fopen($source,'rb')) {
			$sql = "";
			while($f && !feof($f)) {
				$chunk = fread($f, 65535);
				$sql .= $chunk;
			}
			fclose($f);
			$this->fileastext = $sql;
			$success = true;
			return $success;
		} else {
			return $success;
		}
	}

	/**
	 * Returns 
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function fileToBlob () {
		global $database;
		$source = $this->file_path;
		$success = false;
		
		if ($f = @fopen($source,'rb')) {
			$sql = "";
			while($f && !feof($f)) {
				$chunk = fread($f, 65535);
				$sql .= $chunk;
			}
			fclose($f);
			$this->fileasblob = $sql;
			$this->fileisblob = '1';
			$success = true;
			return $success;
		} else {
			return $success;
		}
	}
		
	/**
	 * Returns
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function textToFile ( $file, $temppath='' ) {
		global $mainframe, $mosConfig_absolute_path;
		$result = false;
		if (!$temppath || !is_writable($temppath)) {
			$temppath = $this->getTempDirectory();
		}
		
		$destination = $temppath.DS.$file->filename;
		
		if ($f = @fopen($destination,'wb')) {
			if ($file->filetext AND fwrite ( $f, $file->filetext )) { $result = $destination; }
			fclose($f);
		}
		
		return $result;
	}
	
	/**
	 * Returns
	 * @param mixed Boolean
	 * @param mixed Boolean
	 * @return array
	 */
	function blobToFile ( $file, $temppath='' ) {
		global $mainframe, $mosConfig_absolute_path;
		$result = false;
		if (!$temppath || !is_writable($temppath)) {
			$temppath = $this->getTempDirectory();
		}
		
		$destination = $temppath.DS.$file->filename;
		
		if ($f = @fopen($destination,'wb')) {
			if ($file->fileblob AND fwrite ( $f, $file->fileblob )) { $result = $destination; }
			fclose($f);
		}
		
		return $result;
	}	

	/**
	 * Retrieves the values
	 * @return array Array of objects containing the data from the database
	 */
	function getStorageMethods() {
		static $instance;
		
		if (!is_array($instance)) {
			$instance = array();
				$instance_file = new stdClass();
				$instance_file->id = 1;
				$instance_file->title = 'File';
			$instance[0] = $instance_file;
				$instance_blob = new stdClass();
				$instance_blob->id = 2;
				$instance_blob->title = 'Blob';
			$instance[1] = $instance_blob;

		}

		return $instance;
	}
	
	/**
	 * Creates a List
	 * @return array Array of objects containing the data from the database
	 */
	function getArrayListStorageMethods() {
		static $instance;
		
		if (!is_array($instance)) {
			$instance = array();
			$data = &HelpDeskFile::getStorageMethods();
			for ($i=0; $i<count($data); $i++) {
				$d = $data[$i];
		  		$instance[] = mosHTML::makeOption( $d->id, HelpDeskText::_( $d->title ) );
			}
		}

		return $instance;
	}	
}

?>